<style>
	.card-action h2 {
    	font-size: 1.25rem;
        margin: 0;
	}
	
	table.mempool-table {
		width: 100%;
		border-spacing: 0;
	}

	table.mempool-table th,
	table.mempool-table td,
	table.mempool-table tr,
	table.mempool-table thead,
	table.mempool-table tfoot
	table.mempool-table tbody { 
		display: block;
		text-align: center
	}

	table.mempool-table thead tr,
	table.mempool-table tfoot tr {
		/* fallback */
		width: 97%;
		/* minus scroll bar width */
		width: -webkit-calc(100% - 16px);
		width:    -moz-calc(100% - 16px);
		width:         calc(100% - 16px);
	}

	table.mempool-table tr:after {
		content: ' ';
		display: block;
		visibility: hidden;
		clear: both;
	}

	table.mempool-table tbody {
		display: block;
		max-height: 214px;
		overflow-y: scroll;
		overflow-x: hidden;
	}

	table.mempool-table thead th,
	table.mempool-table tbody td,
	table.mempool-table tfoot td {
		width: 10%;
		float: left;
	}

	table.mempool-table thead th:first-child,
	table.mempool-table tbody td:first-child,
	table.mempool-table tfoot td:first-child {
		min-width: 20%;
	}

	table.mempool-table thead th:last-child,
	table.mempool-table tbody td:last-child,
	table.mempool-table tfoot td:last-child {
		min-width: 40%;
	}

	td.date-time {
		padding: 2px;
		line-height: 90%;
	}

	table.mempool-table td.date-time {
		padding-top: 10px;
	}

	table.mempool-table {
		min-width: 1178px;
	}

</style>

<div style="height: 10px; clear: both;"></div>

<div class="row">
	<div class="col m4 l4 s12">
		<ul class="collection hoverable">
			<li class="collection-item">
				Height: <span id="networkHeight" class="value light-blue-text text-darken-4"></span>
			</li>
			<li class="collection-item">
				Transactions: <span id="networkTransactions" class="value light-blue-text text-darken-4"></span>
			</li>
			<li class="collection-item">
				Supply: <span class="value light-blue-text text-darken-4"><span id="totalCoins"></span>
						(<span id="emissionPercent"></span>)</span>
			</li>
		</ul>
	</div>
	<div class="col m4 l4 s12">
		<ul class="collection hoverable">
			<li class="collection-item">
				Difficulty: <span id="networkDifficulty" class="value light-blue-text text-darken-4"></span>
			</li>		
			<li class="collection-item">
				Hashrate: <span id="networkHashrate" class="value light-blue-text text-darken-4"></span>
			</li>
			<li class="collection-item">
				Est. T: <span id="blockSolveTime" class="value light-blue-text text-darken-4"></span>
			</li>
		</ul>
	</div>
	<div class="col m4 l4 s12">
		<ul class="collection hoverable">
			<li class="collection-item">
				Reward: <span id="currentReward" class="value light-blue-text text-darken-4"></span>
			</li>
			<li class="collection-item">
				Min. fee: <span id="minimumFee" class="value light-blue-text text-darken-4"></span>
			</li>
			<li class="collection-item">
				Avg. T: <span id="avgSolveTime" class="value light-blue-text text-darken-4"></span>
			</li>
		</ul>
	</div>
</div>
<div class="row">
	<div class="col m12 l12 s12">
		<div class="card hoverable">
			<div class="card-content">
				<div class="d-flex align-items-center">
					<div class="ml-auto">
						<canvas id="difficultyChart" height="250"></canvas>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<div class="row">
	<div class="col s12">
		<div class="card hoverable">
			<div class="card-action grey lighten-5">
				<h2 class="light-blue-text text-darken-4"><span class="tooltipped"
					data-position="bottom" data-tooltip="Recent transactions waiting to be included into a block.">
					<i class="fas fa-exchange-alt"></i> Transactions pool</span></h2>
			</div>
			<div class="card-content">
				<div id="empty_mem_pool" style="display: none;">
					<p>No pending transactions.</p>
				</div>
				<div id="mem_pool" style="display: block;">
					<div class="row">
						<div class="col s12 table-responsive">
							<table class="highlight centered mempool-table" id="mem_pool_table">
								<thead>
									<tr>
										<th><i class="far fa-clock"></i> Date &amp; time</th>
										<th><i class="fas fa-money-bill-wave-alt"></i> Amount</th>
										<th><i class="fas fa-donate"></i> Fee</th>
										<th><i class="far fa-hdd"></i> Size</th>
										<th><i class="fas fa-paw"></i> Hash</th>
									</tr>
								</thead>
								<tbody id="mem_pool_rows"></tbody>
								<tfoot>
									<tr>	
										<td>
											Total <span class="badge black-text" id="mempool_count"></span>
										</td>
										<td>
											<span id="mempool_amount"></span>
										</td>
										<td>
											<span id="mempool_fees"></span>
										</td>
										<td>
											<span id="mempool_sizes"></span>
										</td>
										<td>
											<!-- empty cell for hash -->
										</td>
									</tr>
								</tfoot>
							</table>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<div class="row">
	<div class="col s12">
		<div class="card hoverable">
			<div class="card-action grey lighten-5">
				<h2 class="light-blue-text text-darken-4"><i class="fas fa-link"></i> Recent blocks</h2>
				<a class="btn-floating btn-large halfway-fab waves-effect waves-light light-blue darken-1" id="loadMoreBlocks"><i class="material-icons">add</i></a>
			</div>
			
			<div class="card-content">
				<div class="row">
					<div class="col l10 s12">
						<a id="first-page" href="#" class="btn light-blue darken-3">
							<i class="fa fa-step-backward" aria-hidden="true"></i>
							First
						</a>
						<a id="prev-page" href="#" class="btn light-blue darken-3">
							<i class="fa fa-backward" aria-hidden="true"></i>
							Older
						</a>
						<div class="input-field inline">
							<input id="goto-height" type="text" placeholder="Height">
						</div>
						<a id="goto-height-go" href="#" class="btn light-blue darken-3">Go</a>
						<a id="next-page" href="#" class="btn light-blue darken-3 disabled">
							Newer
							<i class="fa fa-forward" aria-hidden="true"></i>
						</a>
						<a id="last-page" href="#" class="btn light-blue darken-3 disabled">
							Last
							<i class="fa fa-step-forward" aria-hidden="true"></i>
						</a>
					</div>
					<div class="col l2 s12">
						<div class="input-field col s12">
							<select id="select_blocks_count">
								<option value="10">10</option>
								<option value="20" selected>20</option>
								<option value="50">50</option>
								<option value="100">100</option>
							</select>
							<label>Blocks per page</label>
						</div>
					</div>
				</div>
				<div class="table-responsive">
					<table class="highlight centered">
						<thead>
							<tr>
								<th><i class="fas fa-bars"></i> Height</th>
								<th><i class="far fa-clock"></i> Date, time &amp; age</th>
								<th><i class="fas fa-hourglass-end"></i> Lapse</th>
								<th><i class="fas fa-paw"></i> Block hash</th>
								<th><i class="far fa-hdd"></i> Size</th>
								<th><i class="fas fa-unlock-alt"></i> Difficulty</th>
								<th><i class="fas fa-exchange-alt"></i> Txs</th>
							</tr>
						</thead>
						<tbody id="blocks_rows">
		
						</tbody>
					</table>
				</div>
			</div>
		</div>
	</div>
</div>

<div class="row">
	<div class="col s12">
		<div class="card hoverable">
			<div class="card-action grey lighten-5">
				<h2 class="light-blue-text text-darken-4"><span class="tooltipped"
					data-position="bottom" data-tooltip="Alternative blocks stored in node's memory.">
					<i class="fas fa-share-alt"></i> Alt. blocks</span></h2>
			</div>
			<div class="card-content">
				<div id="empty_alt_blocks" style="display: none;">
					<p>No alt. blocks.</p>
				</div>
				<div id="alt_blocks" style="display: block;">
					<div class="row">
						<div class="col s12 table-responsive">
							<table class="highlight centered">
								<thead>
									<tr>
										<th><i class="fas fa-bars"></i> Height</th>
										<th><i class="far fa-clock"></i> Date, time &amp; age</th>
										<th><i class="fas fa-paw"></i> Block hash</th>
										<th><i class="far fa-hdd"></i> Size</th>
										<th><i class="fas fa-unlock-alt"></i> Difficulty</th>
										<th><i class="fas fa-exchange-alt"></i> Txs</th>
									</tr>
								</thead>
								<tbody id="alt_blocks_rows">
				
								</tbody>
							</table>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<script>
	var block,
		Difficulties = [],
		MinFees = [],
		Blocks = [],
		Rewards = [],
		Txses = [],
		Sizes = [],
		DateTimes = [],
		Timestamps = [],
		Solvetimes = [],
		diffChart,
		alt_blocks,
		refresh = true;

	var coinsInCirculation;
	var lastBaseReward;

	$(document).ready(function(){
		$('select').formSelect();
	});

	currentPage = {
		destroy: function () {
			if (xhrGetBlocks) xhrGetBlocks.abort();
		},
		init: function () {
			renderLastStats();
			$("#count_val").text(blocksPerPage);
			$.when(
				renderInitialBlocks()
			).then(function () {
				$.when(
					displayDiffChart()
				).then(function () {
					setTimeout(function () {
						refreshChart();
						var currHeight = $('#blocks_rows').children().first().data(
							'height');
						if (currHeight + blocksPerPage >= lastStats.last_known_block_index) {
							$('#next-page').addClass('disabled');
							$('#last-page').addClass('disabled');
							$('#loadMoreBlocks').removeClass('disabled');
						} else {
							$('#next-page').removeClass('disabled');
							$('#last-page').removeClass('disabled');
						}
						if (currHeight - blocksPerPage <= 0) {
							$('#prev-page').addClass('disabled');
							$('#first-page').addClass('disabled');
							$('#loadMoreBlocks').addClass('disabled');
						}
					}, 100)
				})
			});
			getAltBlocks();
			alt_blocks = lastStats.alt_blocks_count;
		},
		update: function () {
			renderLastStats();
			$("time.timeago").timeago();
			getPoolTransactions();
			var currHeight = $('#blocks_rows').children().first().data('height');
			if (currHeight + blocksPerPage < lastStats.last_known_block_index) {
				refresh = false;
			}
			if (refresh) {
				$.when(
					renderInitialBlocks()
				).then(function () {
					refreshChart();
					$('.tooltipped').tooltip();
				});
			}
			if (currHeight + blocksPerPage < lastStats.last_known_block_index) {
				$('#next-page').removeClass('disabled');
				$('#last-page').removeClass('disabled');
			}
			
			if (alt_blocks !== lastStats.alt_blocks_count) {
				getAltBlocks();
				alt_blocks = lastStats.alt_blocks_count;
			}
		}
	};

	function renderLastStats() {
		updateText('networkHeight', lastStats.height.toString());
		updateText('networkTransactions', lastStats.transactions_count.toString());
		updateText('networkDifficulty', getReadableDifficultyString(lastStats.difficulty, 2).toString());
		updateText('totalCoins', getReadableCoins(parseInt(lastStats.already_generated_coins.replace('.', '')), 2));
		updateText('emissionPercent', (parseInt(lastStats.already_generated_coins.replace('.', '')) /
			10000000000000000000 * 100).toFixed(4) + "%");
		updateText('currentReward', getReadableCoins(lastStats.next_reward, 4));
		updateText('networkHashrate', getReadableHashRateString(lastStats.difficulty / blockTargetInterval));
		updateText('minimumFee', getReadableCoins(lastStats.min_fee, 6));
	}

	var xhrGetBlocks;
	$('#loadMoreBlocks').click(function () {
		if (xhrGetBlocks) xhrGetBlocks.abort();
		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_blocks_list",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: $('#blocks_rows').children().last().data('height')
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					var currHeight = $('#blocks_rows').children().last().data('height');
					if (currHeight === 0) {
						$('#loadMoreBlocks').toggleClass('disabled');
					}
					setTimeout(function () {
						loadMoreChart();
					}, 100)
				});
			}
		});
	});

	$('#prev-page').click(function (e) {
		refresh = false;
		clearArrays();
		if (xhrGetBlocks) xhrGetBlocks.abort();
		var currHeight = $('#blocks_rows').children().first().data('height');
		var openHeight = (currHeight - blocksPerPage <= 0) ? blocksPerPage : currHeight - blocksPerPage;

		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_prev_nav",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: openHeight
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$('#blocks_rows').children().remove();
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					setTimeout(function () {
						refreshChart();
					}, 100)
				});
			}
		});
		e.preventDefault();

		if (currHeight + blocksPerPage >= lastStats.last_known_block_index) {
			$('#next-page').removeClass('disabled');
			$('#last-page').removeClass('disabled');
			$('#loadMoreBlocks').removeClass('disabled');
		}
		if (currHeight - blocksPerPage * 2 <= 0) {
			$('#prev-page').addClass('disabled');
			$('#first-page').addClass('disabled');
			$('#loadMoreBlocks').addClass('disabled');
		}
	});

	$('#next-page').click(function (e) {
		refresh = false;
		clearArrays();
		if (xhrGetBlocks) xhrGetBlocks.abort();
		var currHeight = $('#blocks_rows').children().first().data('height');
		var openHeight = (currHeight + blocksPerPage > lastStats.last_known_block_index) ? lastStats
			.last_known_block_index : currHeight + blocksPerPage;

		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_next_nav",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: openHeight
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$('#blocks_rows').children().remove();
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					setTimeout(function () {
						refreshChart();
					}, 100)
				});
			}
		});
		e.preventDefault();

		if ((currHeight + blocksPerPage) >= lastStats.last_known_block_index) {
			$('#next-page').addClass('disabled');
			$('#last-page').addClass('disabled');
			refresh = true;
		}

		if (!(currHeight + $('#blocks_rows').size() - blocksPerPage <= 0)) {
			$('#loadMoreBlocks').removeClass('disabled');
		}

		$('#prev-page').removeClass('disabled');
		$('#first-page').removeClass('disabled');

	});

	$('#first-page').click(function (e) {
		refresh = false;
		clearArrays();
		if (xhrGetBlocks) xhrGetBlocks.abort();
		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_first_nav",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: blocksPerPage
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$('#blocks_rows').children().remove();
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					setTimeout(function () {
						refreshChart();
					}, 100)
				});
			}
		});
		e.preventDefault();

		$('#next-page').removeClass('disabled');
		$('#last-page').removeClass('disabled');
		$('#prev-page').addClass('disabled');
		$('#first-page').addClass('disabled');
		$('#loadMoreBlocks').addClass('disabled');
	});

	$('#last-page').click(function (e) {
		refresh = true;
		clearArrays();
		if (xhrGetBlocks) xhrGetBlocks.abort();
		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_last_nav",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: lastStats.last_known_block_index
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$('#blocks_rows').children().remove();
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					setTimeout(function () {
						refreshChart();
					}, 100)
				});
			}
		});
		e.preventDefault();

		$('#next-page').addClass('disabled');
		$('#last-page').addClass('disabled');
		$('#prev-page').removeClass('disabled');
		$('#first-page').removeClass('disabled');
		$('#loadMoreBlocks').removeClass('disabled');
	});

	$('#goto-height-go').click(function (e) {
		var gotoHeight = parseInt(document.getElementById('goto-height').value);
		clearArrays();
		
		if (xhrGetBlocks) xhrGetBlocks.abort();
		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_goto_height",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: gotoHeight
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$('#blocks_rows').children().remove();
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					setTimeout(function () {
						refreshChart();
						var currHeight = $('#blocks_rows').children().first().data(
						'height');
						if (currHeight + blocksPerPage >= lastStats.last_known_block_index) {
							$('#next-page').addClass('disabled');
							$('#last-page').addClass('disabled');
							$('#loadMoreBlocks').removeClass('disabled');
							refresh = true;
						} else {
							$('#next-page').removeClass('disabled');
							$('#last-page').removeClass('disabled');
							refresh = false;
						}
						if (currHeight - blocksPerPage <= 0) {
							$('#prev-page').addClass('disabled');
							$('#first-page').addClass('disabled');
							$('#loadMoreBlocks').addClass('disabled');
							refresh = false;
						}
					}, 100)
				});
			}
		});

		e.preventDefault();
	});

	$('#goto-height').keyup(function (e) {
		if (e.keyCode === 13)
			$('#goto-height-go').click();
	});

	$("#select_blocks_count").on('change', function (e) {
		clearArrays();
		blocksPerPage = parseInt(e.target.value);
		var currHeight = $('#blocks_rows').children().first().data('height');
		if (xhrGetBlocks) xhrGetBlocks.abort();
		xhrGetBlocks = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_block_count",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: currHeight
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				$('#blocks_rows').children().remove();
				$.when(
					renderBlocks(data.result.blocks)
				).then(function () {
					setTimeout(function () {
						refreshChart();
					}, 100)
				});
			}
		});

		if (currHeight + blocksPerPage >= lastStats.last_known_block_index) {
			$('#next-page').addClass('disabled');
			$('#last-page').addClass('disabled');
		} else {
			$('#next-page').removeClass('disabled');
			$('#last-page').removeClass('disabled');
			refresh = false;
		}
		$('#prev-page').removeClass('disabled');
		$('#first-page').removeClass('disabled');
		$('#loadMoreBlocks').removeClass('disabled');
		if (currHeight - blocksPerPage <= 0) {
			$('#prev-page').addClass('disabled');
			$('#first-page').addClass('disabled');
			$('#loadMoreBlocks').addClass('disabled');
		}
	});

	function clearArrays() {
		Difficulties = [];
		MinFees = [];
		Blocks = [];
		Rewards = [];
		Txses = [];
		Sizes = [];
		DateTimes = [];
		Timestamps = [];
		Solvetimes = [];
	}

	function renderInitialBlocks() {
		var loadHeight;
		if (urlParam('height'))
			loadHeight = parseInt(urlParam('height'));
		else
			loadHeight = lastStats.height - 1;

		if ((loadHeight - blocksPerPage) < 0) {
			$('#prev-page').addClass('disabled');
			$('#next-page').removeClass('disabled');
		}

		return $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_init_blocks",
				method: "getblockslist",
				params: {
					count: blocksPerPage,
					height: loadHeight
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				renderBlocks(data.result.blocks);
			}
		});
	};

	function getBlockRowElement(block, jsonString) {
		var row = document.createElement('tr');
		row.setAttribute('data-json', jsonString);
		row.setAttribute('data-height', block.height);
		row.setAttribute('id', 'blockRow' + block.height);
		row.setAttribute('title', block.hash);
		var dateTime = block.timestamp === 0 ? new Date(1464595200 * 1000).toISOString() : new Date(block.timestamp * 1000)
			.toISOString(); // quirk not to show 1970 and freeze chart because in genesis tx there's 0 instead of timestamp
		row.setAttribute('data-dt', dateTime);
		row.setAttribute('data-min-fee', parseFloat(getReadableCoins(block.min_fee, 6, false)));
		var columns =
			'<td>' + block.height + '</td>' +
			'<td class="date-time">' + formatDate(block.timestamp) + '<br />(<time class="timeago" datetime="' + dateTime + '"></time>)</td>' +
			'<td class"solvetime">' + formatTime(block.solvetime) + '</td>' +
			'<td>' + formatBlockLink(block.hash) + '</td>' +
			'<td>' + formatBytes(parseInt(block.cumulative_size)) + '</td>' +
			'<td class="blk-diff">' + block.difficulty + '</td>' +
			'<td>' + block.transactions_count + '</td>';

		Difficulties.push(parseInt(block.difficulty));
		MinFees.push(parseFloat(getReadableCoins(block.min_fee, 6, false)));
		Blocks.push(parseInt(block.height));
		Txses.push(parseInt(block.transactions_count));
		Sizes.push(parseInt(block.cumulative_size));
		DateTimes.push(dateTime);
		Timestamps.push(block.timestamp);

		row.innerHTML = columns;

		return row;
	}

	function renderBlocks(blocksResults) {
		var $blocksRows = $('#blocks_rows');
		for (var i = 0; i < blocksPerPage; i++) {
			Solvetimes.push(Math.abs(blocksResults[i].timestamp - blocksResults[i + 1].timestamp));
			var block = blocksResults[i];
			block.solvetime = Math.abs(blocksResults[i].timestamp - blocksResults[i + 1].timestamp);
			var blockJson = JSON.stringify(block);
			var existingRow = document.getElementById('blockRow' + block.height);
			if (existingRow && existingRow.getAttribute('data-json') !== blockJson) {
				$(existingRow).replaceWith(getBlockRowElement(block, blockJson));
			} else if (!existingRow) {
				var blockElement = getBlockRowElement(block, blockJson);
				var inserted = false;
				var rows = $blocksRows.children().get();
				for (var f = 0; f < rows.length; f++) {
					var bHeight = parseInt(rows[f].getAttribute('data-height'));
					if (bHeight < block.height) {
						inserted = true;
						$(rows[f]).before(blockElement);
						break;
					}
				}
				if (!inserted) {
					$blocksRows.append(blockElement);
				}
			}
		}
		$("time.timeago").timeago();
		calcAvgHashRate();
		calcAvgSolveTime();
	}

	function getAltBlocks() {
		return $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_alt_blocks",
				method: "getaltblockslist",
				params: {
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				renderAltBlocks(data.result.alt_blocks);

				if (data.result.alt_blocks.length == 0) {
					$('#alt_blocks').hide();
					$('#empty_alt_blocks').show();
				} else {
					$('#alt_blocks').show();
					$('#empty_alt_blocks').hide();
				}
			}
		});
	};


	function getAltBlockRowElement(block, jsonString) {
		var row = document.createElement('tr');
		row.setAttribute('data-json', jsonString);
		row.setAttribute('data-height', block.height);
		row.setAttribute('id', 'altBlockRow_' + block.height);
		row.setAttribute('title', block.hash);
		var dateTime = block.timestamp === 0 ? new Date(1464595200 * 1000).toISOString() : new Date(block.timestamp * 1000)
			.toISOString(); // quirk not to show 1970 and freeze chart because in genesis tx there's 0 instead of timestamp
		row.setAttribute('data-dt', dateTime);
		var columns =
			'<td>' + block.height + '</td>' +
			'<td class="date-time">' + formatDate(block.timestamp) + '<br />(<time class="timeago" datetime="' + dateTime + '"></time>)</td>' +
			'<td>' + formatBlockLink(block.hash) + '</td>' +
			'<td>' + formatBytes(parseInt(block.cumulative_size)) + '</td>' +
			'<td class="blk-diff">' + block.difficulty + '</td>' +
			'<td>' + block.transactions_count + '</td>';

		row.innerHTML = columns;

		return row;
	}

	function renderAltBlocks(blocksResults) {
		var $blocksRows = $('#alt_blocks_rows');
		for (var i = 0; i < blocksResults.length; i++) {
			var block = blocksResults[i];
			var blockJson = JSON.stringify(block);
			var existingRow = document.getElementById('altBlockRow_' + block.height);
			if (existingRow && existingRow.getAttribute('data-json') !== blockJson) {
				$(existingRow).replaceWith(getAltBlockRowElement(block, blockJson));
			} else if (!existingRow) {
				var blockElement = getAltBlockRowElement(block, blockJson);
				var inserted = false;
				var rows = $blocksRows.children().get();
				for (var f = 0; f < rows.length; f++) {
					var bHeight = parseInt(rows[f].getAttribute('data-height'));
					if (bHeight < block.height) {
						inserted = true;
						$(rows[f]).before(blockElement);
						break;
					}
				}
				if (!inserted) {
					$blocksRows.append(blockElement);
				}
			}
		}
		$("time.timeago").timeago();
	}

	function calcAvgHashRate() {
		var sum = Difficulties.reduce(add, 0);
		function add(a, b) {
			return a + b;
		}
		var avgDiff = Math.round(sum / Difficulties.length);
		var avgHashRate = avgDiff / blockTargetInterval;

		//updateText('avgDifficulty', getReadableDifficultyString(avgDiff, 2).toString());
		//updateText('avgHashrate', getReadableHashRateString(avgDiff / blockTargetInterval));
		updateText('blockSolveTime', getReadableTime(lastStats.difficulty / avgHashRate));
	}

	function calcAvgSolveTime() {
		ts = Timestamps.concat([]);
		ts.sort();
		var avg_solve_time = 0;
		var solveTime = 0;
		for (var i = 1; i < ts.length; i++) {
			solveTime += ts[i] - ts[i - 1];
		}
		avg_solve_time = solveTime / (ts.length - 1);
		updateText('avgSolveTime', getReadableTime(avg_solve_time));
	}

	//  MemPool Transactions
	function getPoolTransactions() {
		var xhrGetPool = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "explorer_mempool",
				method: "gettransactionspool",
				params: {}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (newdata) {
				if (typeof newdata.result !== "undefined") {
					var data = newdata.result.transactions;
					var totalAmount = 0;
					var totalFee = 0;
					var totalSize = 0;
					var txcount = 0;
					var txsRows = document.getElementById('mem_pool_rows');
					if (txsRows) {
						while (txsRows.firstChild) {
							txsRows.removeChild(txsRows.firstChild);
						}
					}
					for (var i = 0; i < data.length; i++) {
						var tx = data[i];

						var row = document.createElement('tr');
						var columns =
							'<td class="date-time">' + formatDate(tx.receive_time) + '<br />(<span class="mtx-ago"></span>)' +
							'</td>' +
							'<td>' + getReadableCoins(tx.amount_out, 4, true) + '</td>' +
							'<td>' + getReadableCoins(tx.fee, 4, true) + '</td>' +
							'<td>' + formatBytes(parseInt(tx.size)) + '</td>' +
							'<td>' + formatPaymentLink(tx.hash) + '</td>';
						row.innerHTML = columns;
						$(txsRows).append(row);
						$(row).find('.mtx-ago').timeago('update', new Date(tx.receive_time * 1000)
						.toISOString());

						txcount = txcount + 1;
						totalAmount = tx.amount_out + totalAmount;
						totalFee = totalFee + tx.fee;
						totalSize = totalSize + tx.size;

					}
					updateText('mempool_count', txcount);
					updateText('mempool_amount', getReadableCoins(totalAmount, 4));
					updateText('mempool_fees', getReadableCoins(totalFee, 4));
					updateText('mempool_sizes', formatBytes(parseInt(totalSize)));

					if (data.length == 0) {
						$('#mem_pool').hide();
						$('#empty_mem_pool').show();
					} else {
						$('#mem_pool').show();
						$('#empty_mem_pool').hide();
					}
				}
			}
		});
	}

	// Difficulty chart
	function displayDiffChart() {
		var ctx = document.getElementById("difficultyChart");
		var chartData = {
			labels: [].concat(formatDate(DateTimes)).reverse(),
			datasets: [
			{
				data: [].concat(Blocks).reverse(),
				yAxisID: "Height",
				label: "Height",
				backgroundColor: "rgba(0,0,0,0)",
				borderColor: "rgba(0,0,0,0)",
				borderWidth: 0,
				pointBorderWidth: 0,
				pointRadius: 0,
				pointHoverRadius: 0,
				pointHitRadius: 0,
				display: false,
				type: 'line'
			}, {
				data: [].concat(Difficulties).reverse(),
				yAxisID: "Difficulty",
				label: "Difficulty",
				backgroundColor: "rgba(47,164,231,0)",
				borderColor: '#2FA4E7',
				borderWidth: 3,
				pointColor: "#2FA4E7",
				pointBorderColor: "#2FA4E7",
				pointHighlightFill: "#2FA4E7",
				pointBackgroundColor: "#2FA4E7",
				pointBorderWidth: 1,
				pointRadius: 2,
				pointHoverRadius: 3,
				pointHitRadius: 5,
				type: 'line'
			}, {
				data: [].concat(MinFees).reverse(),
				yAxisID: "MinFee",
				label: "Minimum fee",
				backgroundColor: "rgba(237,28,36,0)",
				borderColor: '#ED1C24',
				borderWidth: 1,
				pointColor: "#ED1C24",
				pointBorderColor: "#ED1C24",
				pointHighlightFill: "#ED1C24",
				pointBackgroundColor: "#ED1C24",
				pointBorderWidth: 1,
				pointRadius: 2,
				pointHoverRadius: 3,
				pointHitRadius: 5,
				type: 'line'
			}, {
				data: [].concat(Txses).reverse(),
				yAxisID: "Transactions",
				label: "Transactions",
				backgroundColor: "rgba(100,255,218,0.5)",
				borderWidth: 0,
				pointHitRadius: 5,
				type: 'bar'
			}, {
				data: [].concat(Sizes).reverse(),
                yAxisID: "Sizes",
                label: "Size, bytes",
                backgroundColor: "rgba(198,255,0,0.5)",
                data: [].concat(Solvetimes).reverse(),
                borderColor: '#99D9EA',
				borderWidth: 0,
				pointHitRadius: 5,
                type: 'bar'
            }, {
				data: [].concat(Solvetimes).reverse(),
				yAxisID: "Solvetimes",
				label: "Solve time, s",
				backgroundColor: "rgba(255,192,0,0.1)",
				borderColor: '#FFC000',
				borderWidth: 0,
				pointHitRadius: 5,
				type: 'bar'
			}]
		};
		var options = {
			responsive: true,
			maintainAspectRatio: false,
			elements: {
				line: {
					tension: 0
				}
			},
			title: {
				display: false,
				text: 'Network difficulty, Blocks info and Min. fee',
				fontFamily: "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif;"
			},
			legend: {
				display: false,
				labels: {
					position: 'top',
					filter: function(legendItem, chartData) {
						if (legendItem.datasetIndex === 0) {
							return false;
						}
						return true;
					}
				}
			},
			onClick: graphClickEvent,
			scales: {
				yAxes: [
					{
						id: 'Height',
						type: 'linear',
						position: 'left',
						scaleLabel: {
							display: false,
							labelString: 'Height'
						},
						gridLines: {
							display: false
						},
						ticks: {
							fontSize: 9,
							display: false
						},
						display: false
					}, {
						id: 'Difficulty',
						type: 'linear',
						position: 'left',
						scaleLabel: {
							display: true,
							labelString: 'Difficulty'
						},
						gridLines: {
							display: false
						},
						ticks: {
							fontSize: 8,
							display: true,
							callback: function(value) {
								return getReadableDifficultyString(value, 2);
							},
						},
						display: true
					}, {
						id: 'Transactions',
						type: 'linear',
						position: 'right',
						scaleLabel: {
							display: false,
							labelString: 'Transactions'
						},
						gridLines: {
							display: false
						},
						ticks: {
							fontSize: 9,
							display: false
						},
						display: false
					}, {
						id: 'Sizes',
						type: 'linear',
						position: 'right',
						scaleLabel: {
							display: false,
							labelString: 'Size'
						},
						gridLines: {
							display: false
						},
						ticks: {
							fontSize: 9,
							display: false
						},
						display: false
					}, {
						id: 'MinFee',
						type: 'linear',
						position: 'right',
						scaleLabel: {
							display: true,
							labelString: 'Minimum fee'
						},
						gridLines: {
							display: false
						},
						ticks: {
							fontSize: 8,
							display: true,
							suggestedMin: 0.001,
							suggestedMax: 0.1
						},
						display: true
					}, {
						id: 'Solvetimes',
						type: 'linear',
						position: 'right',
						scaleLabel: {
							display: false,
							labelString: 'Solve time'
						},
						gridLines: {
							display: false
						},
						ticks: {
							fontSize: 9,
							display: false
						},
						display: false
					}
				],
				xAxes: [{
					stacked: true,
					type: "time",
					categoryPercentage: 0,
					barPercentage: 1,
					categorySpacing: 0,
					barThickness: 5,
					time: {
						parser: false,
						unit: 'minute',
						unitStepSize: 60,
						round: 'second',
						displayFormats: {
							'millisecond': 'SSS [ms]',
							'second': 'HH:mm:ss', // 11:20:01 AM
							'minute': 'HH:mm', // 11:20:01 AM
							'hour': 'HH:mm', // Sept 4, 5PM
							'day': 'MMM Do', // Sep 4 2015
							'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?
							'month': 'MMM YYYY', // Sept 2015
							'quarter': '[Q]Q - YYYY', // Q3
							'year': 'YYYY', // 2017
						},
					},
					gridLines: {
						color: '#D2D2D2',
						display: false
					},
					ticks: {
						fontSize: 9,
						autoSkip: true,
						maxRotation: 0,
						//minRotation: 90
					}
				}]
			},
			tooltips: {
				mode: 'index',
				intersect: true,
				callbacks: {
					title: function (tooltipItem, data) {
						var height = data.datasets[3].data[tooltipItem[0].index];
						var time = new Date(data.labels[tooltipItem[0].index]).toLocaleString();
						return time + '';
					}
				}
			},
			hover: {
				onHover: function(e, el) {
					$("#difficultyChart").css("cursor", el[0] ? "pointer" : "default");
				}
			}
		};

		diffChart = new Chart(ctx, {
			type: 'bar',
			data: chartData,
			options: options
		});
	}

	function refreshChart() {
		var brows = $('#blocks_rows').children(),
			labels = [],
			diffs = [],
			sizes = [],
			times = [],
			heights = [],
			txsnr = [],
			mfees = [],
			lapses = [];
		for (var i = 0; i < brows.length; i++) {
			var row = $(brows[i]);
			var label = row.data("json").height;
			var diff = row.data("json").difficulty;
			var txses = row.data("json").transactions_count;
			var size = row.data("json").cumulative_size;
			var time = row.attr('data-dt');
			var mfee = row.attr('data-min-fee');
			var lapse = row.data("json").solvetime;

			labels.push(label);
			diffs.push(diff);
			txsnr.push(txses);
			sizes.push(size);
			times.push(time);
			mfees.push(mfee);
			lapses.push(lapse);
		}

		if (diffChart != undefined) {
			diffChart.data.labels = times.reverse();
			diffChart.data.datasets[0].data = labels.reverse();
			diffChart.data.datasets[1].data = diffs.reverse();
			diffChart.data.datasets[2].data = mfees.reverse();
			diffChart.data.datasets[3].data = txsnr.reverse();
			diffChart.data.datasets[4].data = sizes.reverse();
			diffChart.data.datasets[5].data = lapses.reverse();

			diffChart.update();
		}

	}

	function loadMoreChart() {
		diffChart.data.labels = [].concat(DateTimes).reverse();
		diffChart.data.datasets[0].data = [].concat(Blocks).reverse();
		diffChart.data.datasets[1].data = [].concat(Difficulties).reverse();
		diffChart.data.datasets[2].data = [].concat(MinFees).reverse();
		diffChart.data.datasets[3].data = [].concat(Txses).reverse();
		diffChart.data.datasets[4].data = [].concat(Sizes).reverse();
		diffChart.data.datasets[5].data = [].concat(Solvetimes).reverse();

		diffChart.update();
	}

	function graphClickEvent(event, array) {
		var index = array[0]._index;
		var dataValue = diffChart.data.datasets[0].data[index];
		var block, xhrGetSearchBlockbyHeight;
		if (xhrGetSearchBlockbyHeight) xhrGetSearchBlockbyHeight.abort();
		xhrGetSearchBlockbyHeight = $.ajax({
			url: api + '/json_rpc',
			method: "POST",
			data: JSON.stringify({
				jsonrpc: "2.0",
				id: "blockbyheight",
				method: "getblockheaderbyheight",
				params: {
					height: dataValue
				}
			}),
			dataType: 'json',
			cache: 'false',
			success: function (data) {
				if (data.result) {
					block = data.result.block_header;
					window.location.href = getBlockchainUrl(block.hash);
				} else if (data.error) {
					wrongSearchAlert();
				}
			}
		});
	}

	$(function () {
		$('[data-toggle="tooltip"]').tooltip();
	});

	function getReadableTime(seconds) {

		var units = [
			[60, 's.'],
			[60, 'min.'],
			[24, 'h.'],
			[7, 'd.'],
			[4, 'w.'],
			[12, 'м.'],
			[1, 'y.']
		];

		function formatAmounts(amount, unit) {
			var rounded = Math.round(amount);
			return '' + rounded + ' ' + unit + (rounded > 1 ? '' : '');
		}

		var amount = seconds;
		for (var i = 0; i < units.length; i++) {
			if (amount < units[i][0])
				return formatAmounts(amount, units[i][1]);
			amount = amount / units[i][0];
		}
		return formatAmounts(amount, units[units.length - 1][1]);
	}
</script>

<script src="js/Chart.bundle.min.js"></script>